package com.djx.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.djx.ES.SysUser;
import com.djx.ES.UserRepository;
import com.djx.dao.UserMapper;
import com.djx.entity.User;
import com.djx.service.UserService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.similarity.ScriptedSimilarity;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private ElasticsearchRestTemplate template;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRepository repository;

    @Override
    public List<User> findAll() {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        return userMapper.selectList(userQueryWrapper);
    }

    /**
     * 创建索引
     *
     * @return
     */
    public Boolean createIndex() {
        return template.createIndex(SysUser.class);
    }

    /**
     * 删除索引
     *
     * @return
     */
    public Boolean deleteIndex() {
        return template.deleteIndex("user_index");
    }


    @Override
    public Boolean exit(String index) {
        return template.indexExists(index);
    }

    @Override
    public void importES() {
        //导入之前先删除
        repository.deleteAll();


        List<User> all = findAll();
        List<SysUser> sysUsers = JSON.parseArray(JSON.toJSONString(all), SysUser.class);
        repository.saveAll(sysUsers);
    }

    @Override
    public void deleteAll() {
        repository.deleteAll();
    }


    public void save() {
        SysUser sysUser = new SysUser();
//        sysUser.setId(10);
        sysUser.setEmail("liuhanhan@163.com");
        sysUser.setUsername("刘荣华");
        sysUser.setNickname("刘憨憨");
        sysUser.setPassword("liuhanhan163.com");
        sysUser.setStatus("1");
        repository.save(sysUser);
    }


    public void delete() {

        //根据 对象删不太好使  好像只能 id 可也操作
        SysUser sysUser = new SysUser();
        sysUser.setUsername("刘荣华");
        repository.delete(sysUser);

//        repository.deleteById(1);
    }

    @Override
    public Map<String, Object> queryAll() {
        Iterable<SysUser> all = repository.findAll();
        String s = JSON.toJSONString(all);
        Map<String, Object> params = JSONObject.parseObject(s, new TypeReference<Map<String, Object>>() {
        });
        return params;

    }


    public List<Map<String, Object>> queryPage(Integer pageNo, Integer pageSize, String keywords) throws IOException {
        //设置查询指定的某个文档库：
        SearchRequest searchRequest = new SearchRequest("user_index");
        //查询多个文档库，其中多个文档库名之间用逗号隔开
        //SearchRequest searchRequest = new SearchRequest("posts2","posts", "posts2", "posts1");

        // 条件构造器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("username", keywords);
        sourceBuilder.query(termQueryBuilder);
        // 设置超时时间
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //分页
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);
        // 数据源 查询
        searchRequest.source(sourceBuilder);

        // 执行搜索
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit document : search.getHits().getHits()) {
            list.add(document.getSourceAsMap());
        }
        return list;
    }



    @Override
    public List<Map<String, Object>> searchHeight(Integer pageNo, Integer pageSize, String keywords) throws IOException {
        if (pageNo <= 1) {
            pageNo = 1;
        }
        SearchRequest searchRequest = new SearchRequest("user_index");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("username", keywords);
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("username");
        highlightBuilder.preTags("<span style='color:blue'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);
        highlightBuilder.requireFieldMatch(false);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        ArrayList<Map<String, Object>> list = new ArrayList<>();

        for (SearchHit hit : searchResponse.getHits().getHits()) {
            //解析高亮组字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();

            HighlightField title = highlightFields.get("username");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            //解释高亮的字段，将原来的字段换为我们高亮的字段即可。
            if (title != null) {
                Text[] fragments = title.fragments();
                String newTitle = "";
                for (Text text : fragments) {
                    newTitle += text;
                }
                sourceAsMap.put("username",newTitle);
            }
            list.add(sourceAsMap);
        }
        return list;
    }
}
